package cn.yto.print.system;

import cn.yto.print.config.i18n.I18nResourceManager;
import cn.yto.print.utils.FileLockUtil;
import cn.yto.print.utils.PluginInstalledUtil;
import javafx.application.Platform;
import javafx.embed.swing.SwingFXUtils;
import javafx.scene.image.Image;
import javafx.stage.Stage;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.awt.*;
import java.awt.event.*;
import java.util.Arrays;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Stream;

public class SystemTrayManager {

    private static final Logger logger = LogManager.getLogger(SystemTrayManager.class);
    private static final I18nResourceManager I18N = I18nResourceManager.getInstance();

    private final Stage stage;
    protected JDialog hiddenDialog;

    public SystemTrayManager(Stage stage) {
        this.stage = stage;
    }

    /**
     * 托盘重启
     */
    public static void restartApp() {
        FileLockUtil.releaseLock();
        Process process = PluginInstalledUtil.startUpProcess();
        if (Optional.ofNullable(process).map(Process::isAlive).orElse(false)) {
            Platform.exit();
            System.exit(0);
        }
    }

    /**
     * 添加系统托盘
     */
    public void addSystemTray() {
        if (!SystemTray.isSupported()) {
            logger.info("当前操作系统不支持托盘功能");
            return;
        }
        TrayIcon trayIcon = createTrayIcon();
        JPopupMenu menu = createPopupMenu(trayIcon);

        attachRightClickMenu(trayIcon, menu);
        hiddeSystemTray(menu);
        addHoverSelection(menu);
        addMenuItemCloseEvents(menu);
        handleStageCloseToTray();
        addTrayIconClickToggle(trayIcon);
        addTrayIconToSystemTray(trayIcon);
    }

    private TrayIcon createTrayIcon() {
        Image icon = new Image(Objects.requireNonNull(getClass().getResourceAsStream("/image/icon.png")));
        TrayIcon trayIcon = new TrayIcon(SwingFXUtils.fromFXImage(icon, null), I18N.get("app.show.title"));
        trayIcon.setImageAutoSize(true);
        return trayIcon;
    }

    private JPopupMenu createPopupMenu(TrayIcon trayIcon) {
        configureMenuUI();
        JPopupMenu customMenu = new JPopupMenu();
        customMenu.setPreferredSize(new Dimension(120, 100));

        JMenuItem showMainItem = buildMenuItem("system.tray.show", e -> showMainWindow());
        JMenuItem restartItem = buildMenuItem("system.tray.restart", e -> restartApp());
        JMenuItem exitItem = buildMenuItem("system.tray.exit", e -> exitApplication(trayIcon));

        Stream.of(showMainItem, restartItem, exitItem).forEach(customMenu::add);
        return customMenu;
    }

    private void configureMenuUI() {
        UIManager.put("PopupMenu.background", Color.WHITE);
        UIManager.put("MenuItem.selectionBackground", new Color(200, 200, 200));
        UIManager.put("MenuItem.selectionForeground", Color.BLUE);
    }

    private JMenuItem buildMenuItem(String key, ActionListener action) {
        JMenuItem item = new JMenuItem("    " + I18N.get(key));
        item.setFont(new Font("SansSerif", Font.PLAIN, 15));
        item.setMargin(new Insets(12, 50, 12, 50));
        item.setBorder(new EmptyBorder(0, 0, 0, 0));
        item.addActionListener(action);
        return item;
    }

    private void attachRightClickMenu(TrayIcon trayIcon, JPopupMenu menu) {
        trayIcon.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseReleased(MouseEvent e) {
                if (e.isPopupTrigger()) {
                    Point location = MouseInfo.getPointerInfo().getLocation();
                    int x = e.getX();
                    int y = location.y - menu.getPreferredSize().height;
                    menu.setInvoker(hiddenDialog);
                    hiddenDialog.setLocation(x, y);
                    hiddenDialog.setVisible(true);
                    menu.show(e.getComponent(), x, y);
                }
            }
        });
    }

    private void addHoverSelection(JPopupMenu menu) {
        Arrays.stream(menu.getComponents())
                .filter(JMenuItem.class::isInstance)
                .map(JMenuItem.class::cast)
                .forEach(item -> item.addMouseListener(new MouseAdapter() {
                    @Override
                    public void mouseEntered(MouseEvent e) {
                        item.setArmed(true);
                    }

                    @Override
                    public void mouseExited(MouseEvent e) {
                        item.setArmed(false);
                    }
                }));
    }

    private void addMenuItemCloseEvents(JPopupMenu menu) {
        Arrays.stream(menu.getComponents())
                .filter(JMenuItem.class::isInstance)
                .map(JMenuItem.class::cast)
                .forEach(item -> item.addActionListener(e -> menu.setVisible(false)));
    }

    private void handleStageCloseToTray() {
        stage.setOnCloseRequest(event -> {
            logger.info("主窗口关闭，最小化至系统托盘 ~");
            Platform.setImplicitExit(false);
            event.consume();
            stage.hide();
        });
    }

    private void addTrayIconClickToggle(TrayIcon trayIcon) {
        trayIcon.addActionListener(event -> {
            logger.info("点击托盘图标 [ 双击事件 ] ");
            Platform.runLater(() -> {
                if (stage.isIconified()) {
                    stage.setIconified(false);
                }
                if (!stage.isShowing()) {
                    stage.show();
                    stage.toFront();
                } else {
                    Platform.setImplicitExit(false);
                    stage.hide();
                }
            });
        });
    }

    private void addTrayIconToSystemTray(TrayIcon trayIcon) {
        try {
            SystemTray.getSystemTray().add(trayIcon);
        } catch (Exception e) {
            logger.error("添加系统托盘图标异常", e);
        }
    }

    /**
     * 创建隐藏的 JDialog，用于显示自定义菜单
     */
    private void hiddeSystemTray(JPopupMenu customMenu) {
        hiddenDialog = new JDialog();
        hiddenDialog.setSize(1, 1);
        hiddenDialog.setUndecorated(true);
        hiddenDialog.addWindowFocusListener(new WindowAdapter() {
            @Override
            public void windowLostFocus(WindowEvent e) {
                logger.info("系统托盘失去焦点，隐藏操作菜单 ~");
                hiddenDialog.setVisible(false);
                customMenu.setVisible(false);
            }
        });
    }

    private void showMainWindow() {
        logger.info("点击托盘图标 [ 显示主界面 ] ");
        Platform.runLater(() -> {
            if (stage.isIconified()) {
                stage.setIconified(false);
            }
            stage.show();
            stage.toFront();
        });
    }

    private void exitApplication(TrayIcon trayIcon) {
        logger.info("点击托盘图标 [ 退出小助手 ] ");
        Platform.exit();
        SystemTray.getSystemTray().remove(trayIcon);
        System.exit(0);
    }

}
